﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Principal;
using System.Text;
using BEGDC.CC.BL.Workflow;
using System.Web;
using BEGDC.CC.BL.UserManagement;
using BEGDC.Utility.Castle;
using BEGDC.CC.BL.Common;
using System.Collections;

namespace ASBCC.Business
{
    public class CSPrincipal : CCPrincipal
    {
        /// <summary>
        /// roles is userolesData from cookie , and roles[0] is username , others is real roles
        /// </summary>
        public CSPrincipal(IIdentity identity, string[] roles, string pageName) :
            base(identity, null) //init base CCPrincipal for CCS
        {
            // CIL is username
            CIL = roles[0];
            Role2s = roles.Skip(1).ToArray();
            LoadPageAccessLevel(pageName);
        }

        private string[] role2s;

        /// <summary>
        /// role2s of the pricipal , contains RoleIDs in Role2 split with ";"
        /// </summary>
        public string[] Role2s { 
            get {
                if (HttpContext.Current.Session["AsWho"] == null)
                    return role2s;
                //as a delegater
                else
                {
                    //HttpContext.Current.Session["AsWho"] is employeeNo
                    //get roles in userrole where employeeNo = CIL and delegateuser = Session["AsWho"] and starttime and endtime
                    IUser userService = AppContainer.Instance[ServiceConst.UserService] as IUser;
                    IList userroles = userService.GetDelegationUserRoleListByUserID(HttpContext.Current.Session["AsWho"].ToString(), userService.GetUser(CIL).Id) as IList;

                    List<string> tmp = new List<string>();
                    //tricky : CCUser in COD and CCUser in OCO will add into tmp regardless of whether userroles contains COD or OCO role
                    tmp.Add("10057");
                    tmp.Add("10063");
                    
                    foreach (BEGDC.CC.Entity.UserRole ur in userroles)
                    {
                        tmp.Add((ur.Role.Id + 10000).ToString());
                    }
                    base.SetBackup(userService.GetUserByID(
                        HttpContext.Current.Session["AsWho"].ToString()));
                    return tmp.ToArray();
                    //return userroles.Select(p => (p.Role.Id + 10000).ToString()).ToArray();
                    //each roles + 10000 = Role2s
                    //return null;
                }
            }

            set {
                role2s = value;
            }
        }

        public string Role2String
        {
            get
            {
                string allroles = "";
                var roles = this.Role2s;
                if (roles != null && roles.Count() != 0)
                {
                    foreach (var role in roles)
                    {
                        allroles += role;
                        allroles += ",";
                    }
                    allroles = allroles.Substring(0, allroles.Length - 2);
                }
                return allroles;
            }
        }
        /// <summary>
        /// User CIL Name
        /// </summary>
        public string CIL { get; private set; }
        public AccessLevel AccessLevel { get; set; }
        /// <summary>
        /// AccessDeny string
        /// </summary>
        public static string AccessDenyStr = "Access Denied";

        /// <summary>
        /// load AccessLevel
        /// </summary>
        /// <param name="pageUrl"></param>
        private void LoadPageAccessLevel(string pageName)
        {
            if (IsPageBypassed(pageName.ToLower()))
                return;


            // TODO : to get pages from (this.User as CSPrincipal).Role2s
            var pages = PageHelper.GetEmployeeByUsername(CIL);
            foreach (var page in pages)
            {
                if (pageName.Contains(page.FullName.ToLower()) && page.AccessLevel == 2)
                {
                    AccessLevel = AccessLevel.Write;
                    break;
                }
                if (pageName.Contains(page.FullName.ToLower()) && page.AccessLevel == 1 && AccessLevel != AccessLevel.Write)
                {
                    AccessLevel = AccessLevel.Read;
                }

            }



            bool flag;
            string enableAuthorize = ConfigurationSettings.AppSettings["EnableAuthorize"];
            if (!String.IsNullOrEmpty(enableAuthorize) && bool.TryParse(enableAuthorize, out flag) && flag)
            {
                if (AccessLevel == AccessLevel.Disabled)
                    throw new System.Security.Authentication.AuthenticationException("Access Denied");
            }
        }

        private bool IsPageBypassed(string pageName)
        {
            return BypassList.Any(p => pageName.Contains(p));
        }

        private static string[] BypassList = new string[] { 
            "login.aspx", "logout.aspx", "frameheader.aspx", 
            "framefooter.aspx", "framesidbar.aspx", "entity.js.aspx",
            "workflow.js.aspx", "cilsearch.aspx", "myproperty.aspx" , "cisagreement.aspx" };
    }


}
